#!/usr/bin/env python
# -*- coding:utf-8 -*-
import json

from bottle import Bottle
from bottle import request, response

from conn.MyPagerFactory import MyPager
from conn.MyRedisFactory import RedisConfig

MemwetAdm = Bottle()


@MemwetAdm.hook('before_request')
def validate():
    REQUEST_METHOD = request.environ.get('REQUEST_METHOD')
    HTTP_ACCESS_CONTROL_REQUEST_METHOD = request.environ.get('HTTP_ACCESS_CONTROL_REQUEST_METHOD')
    if REQUEST_METHOD == 'OPTIONS' and HTTP_ACCESS_CONTROL_REQUEST_METHOD:
        request.environ['REQUEST_METHOD'] = HTTP_ACCESS_CONTROL_REQUEST_METHOD


@MemwetAdm.hook('after_request')
def enable_cors():
    response.headers['Access-Control-Allow-Origin'] = '*'  # 允许所有域名的请求
    response.headers['Access-Control-Allow-Methods'] = 'GET, POST, DELETE, PUT, HEAD, OPTIONS'
    response.headers['Access-Control-Allow-Headers'] = 'origin,content-type,accept,authorization,x-requested-with'
    response.headers["Access-Control-Allow-Credentials"] = "true"
    response.headers['Access-Control-Max-Age'] = 86400
    response.status = 200


class MemberWeightRoute:
    ERROR_CODE = {
        "80": "数据读取异常错误，请联系管理员",
        "99": "处理参数错误",
        "100": "数据添加失败，请检查服务端日志",
        "102": "数据更新失败，请检查服务端日志",
        "103": "数据删除失败，请检查服务端日志",
        "104": "数据停止失败，请检查服务端日志",
        "105": "数据恢复失败，请检查服务端日志",
        "106": "数据激活失败，请检查服务端日志",
        "109": "数据不存在，数据处理失败",
    }

    rds_cfg = None
    memberWeightServiceImpl = None

    # weightLossPlanServiceImpl = None

    def __init__(self, memberWeightService, rds_cfg):
        MemberWeightRoute.memberWeightServiceImpl = memberWeightService
        # MemberWeightRoute.weightLossPlanServiceImpl = weightLossPlanService
        MemberWeightRoute.rds_cfg = rds_cfg
        return

    @staticmethod
    @MemwetAdm.get('/fetch')
    def fetch():
        params = {"key": str(request.params.key).replace(" ", ""),
                  "pageSize": request.params.pageSize,
                  "pageNum": request.params.pageNum}
        res = MemberWeightRoute.memberWeightServiceImpl.fetch(param=params)
        if res["code"] != 200:
            return {'code': 99, 'data': None, 'message': MemberWeightRoute.ERROR_CODE["99"]}
        view_list = res['data']
        for _item in view_list:
            if (isinstance(_item['height'], str) and (_item['height'] is None or len(_item['height']) == 0)) or (
                    isinstance(_item['weight'], str) and (_item['weight'] is None or len(_item['weight'])) == 0):
                _item['bmi'] = str(float(0))
                _item['bodyFatRat'] = str(float(0))
            else:
                body_cal_res = MemberWeightRoute.memberWeightServiceImpl.cal_member_weight(view=None,
                                                                                           memberId=_item['member_id'])
                _item['bmi'] = body_cal_res["data"]["BMI"]
                _item['bodyFatRat'] = body_cal_res["data"]["bodyFatRat"]
            _item['close'] = False if _item['status'] == 'MEM-001' else True
            _item['close'] = False if _item['member_sno'] is not None and len(_item['member_sno']) > 0 else True
            if round(float(_item['bmi']), 0) < float(18.5):
                _item['bodyFatRatTag'] = "primary"
                _item['bodyFatRatLabel'] = "偏瘦"
            if float(18.5) <= round(float(_item['bmi']), 0) and round(float(_item['bmi']), 0) < float(23.9):
                _item['bodyFatRatTag'] = "success"
                _item['bodyFatRatLabel'] = "正常"
            if float(24) <= round(float(_item['bmi']), 0) and round(float(_item['bmi']), 0) < float(27.9):
                _item['bodyFatRatTag'] = "warning"
                _item['bodyFatRatLabel'] = "超重"
            if float(28) <= round(float(_item['bmi']), 0) and round(float(_item['bmi']), 0) < float(30):
                _item['bodyFatRatTag'] = "danger"
                _item['bodyFatRatLabel'] = "轻度肥胖"
            if float(30) <= round(float(_item['bmi']), 0) and round(float(_item['bmi']), 0) < float(35):
                _item['bodyFatRatTag'] = "danger"
                _item['bodyFatRatLabel'] = "中度肥胖"
            if float(35) <= round(float(_item['bmi']), 0) and round(float(_item['bmi']), 0):
                _item['bodyFatRatTag'] = "danger"
                _item['bodyFatRatLabel'] = "重度肥胖"
        _pages = MyPager.make_pager(id="table_members", res=view_list, page_size=int(params['pageSize']),
                                    data_total=res['total'], single_pager=False)
        return {'code': 200, 'data': _pages, 'message': ""}

    @staticmethod
    @MemwetAdm.get('/fetchOne')
    def fetch_one():
        memberId = request.params.memberId
        res = MemberWeightRoute.memberWeightServiceImpl.cal_member_weight(view=None, memberId=memberId)
        if res["code"] != 200:
            return {'code': 99, 'data': None, 'message': MemberWeightRoute.ERROR_CODE["99"]}
        RedisConfig.push_val_intimes(MemberWeightRoute.rds_cfg, key=f'hcm:mem:{memberId}_info',
                                     val=json.dumps(res['data'], ensure_ascii=False),
                                     json_flg=True, inTimes=60 * 60)
        return {'code': 200, 'data': res['data'], 'message': ""}

    @staticmethod
    @MemwetAdm.post('/add')
    def add():
        if request.json is not None:
            data = request.json['data']
            res = MemberWeightRoute.memberWeightServiceImpl.add_members(member=data)
            if res['code'] == 200:
                return {'code': 200, 'data': res, 'message': ""}
            else:
                return {'code': res['code'], 'data': res, 'message': MemberWeightRoute.ERROR_CODE["100"]}

    @staticmethod
    @MemwetAdm.post('/update')
    def update():
        if request.json is not None:
            data = request.json['data']
            memberId = data['member_id']
            res = MemberWeightRoute.memberWeightServiceImpl.update_members(member=data, member_id=memberId)
            if res['code'] == 200:
                return {'code': 200, 'data': res, 'message': ""}
            elif res['code'] == 404:
                return {'code': res['code'], 'data': res, 'message': MemberWeightRoute.ERROR_CODE["109"]}
            else:
                return {'code': res['code'], 'data': res, 'message': MemberWeightRoute.ERROR_CODE["102"]}

    @staticmethod
    @MemwetAdm.get('/drop')
    def drop():
        memberId = request.params.memberId
        res = MemberWeightRoute.memberWeightServiceImpl.drop_member(member_id=memberId)
        if res["code"] != 200:
            return {'code': 99, 'data': None, 'message': MemberWeightRoute.ERROR_CODE["103"]}
        elif res['code'] == 404:
            return {'code': res['code'], 'data': res, 'message': MemberWeightRoute.ERROR_CODE["109"]}
        return {'code': 200, 'data': None, 'message': ""}

    @staticmethod
    @MemwetAdm.get('/res')
    def res():
        memberId = request.params.memberId
        res = MemberWeightRoute.memberWeightServiceImpl.res_member(member_id=memberId)
        if res["code"] != 200:
            return {'code': 99, 'data': None, 'message': MemberWeightRoute.ERROR_CODE["105"]}
        elif res['code'] == 404:
            return {'code': res['code'], 'data': res, 'message': MemberWeightRoute.ERROR_CODE["109"]}
        return {'code': 200, 'data': None, 'message': ""}

    @staticmethod
    @MemwetAdm.get('/setMemHeatGap')
    def set_mem_heatgap():
        memberId = request.params.memberId
        heat_gap = request.params.heatgap
        res = MemberWeightRoute.memberWeightServiceImpl.set_mem_heatGap_json(member_id=memberId, heatgap=heat_gap)
        if res["code"] != 200:
            return {'code': 99, 'data': None, 'message': MemberWeightRoute.ERROR_CODE["105"]}
        elif res['code'] == 404:
            return {'code': res['code'], 'data': res, 'message': MemberWeightRoute.ERROR_CODE["109"]}
        return {'code': 200, 'data': None, 'message': ""}

    @staticmethod
    @MemwetAdm.post('/setMemWeight')
    def set_mem_weight_json():
        if request.json is not None:
            data = request.json['data']
            memberId = data["member_id"]
            res = MemberWeightRoute.memberWeightServiceImpl.set_mem_weight_json(member_id=memberId, data=data)
            if res["code"] != 200:
                return {'code': 99, 'data': None, 'message': MemberWeightRoute.ERROR_CODE["105"]}
            elif res['code'] == 404:
                return {'code': res['code'], 'data': res, 'message': MemberWeightRoute.ERROR_CODE["109"]}
            return {'code': 200, 'data': None, 'message': ""}

    @staticmethod
    @MemwetAdm.get('/fetchWeightHis')
    def fetch_weight_his():
        memberId = request.params.memberId
        import datetime
        cal_day = datetime.datetime.now().strftime("%Y-%m-%d")
        res = MemberWeightRoute.memberWeightServiceImpl.fetchWeightHis(member_id=memberId)
        if res["code"] != 200:
            return {'code': 99, 'data': None, 'message': MemberWeightRoute.ERROR_CODE["99"]}
        view_list = res['data']
        if len(view_list) > 0:
            # 会员数据加工，单会员，多个记录模式，并计算最大，最小体重值的日期
            wieght_json_list = [json.loads(i["weight_json"]) for i in view_list]
            sorted_view_list = sorted(wieght_json_list, key=lambda x: float(x["weight"]))
            min_weight = sorted_view_list[0]["weight"]
            max_weight = sorted_view_list[-1]["weight"]
            view_data = {"id": view_list[0]["id"], "member_id": view_list[0]["member_id"], "rrk_his": wieght_json_list,
                         "min_weight": float(min_weight), "max_weight": float(max_weight), "name": view_list[0]["name"]}
            # 制作折线图数据
            series_data = [json.loads(i["weight_json"])["weight"] for i in view_list]
            series_yAxis = [json.loads(i["weight_json"])["cal_date"] for i in view_list]
            line_data = {"series_data": series_data, "series_yAxis": series_yAxis}
        else:
            view_data = []
            line_data = {"series_data": [], "series_yAxis": []}
        return {'code': 200, 'data': view_data, 'line_data': line_data, 'message': ""}

    @staticmethod
    @MemwetAdm.post('/uploadMemWeight')
    def upload_mem_weight_with_file():
        import pandas as pd
        from hcmv.beans.MemberWeightObj import MemberWeight
        if request.json is not None:
            data = request.json['data']
            _obj_id = data['id']
            _obj_load_temp = data['tempId']
            _obj_fileinfo = data['file']
            if _obj_fileinfo is None or len(_obj_fileinfo) == 0:
                return {'code': 200, 'data': None, 'message': ""}
            else:
                if _obj_fileinfo == 'null':
                    return {'code': 200, 'data': None, 'message': ""}
                else:
                    _obj_fileinfo = json.loads(data['file'])
                    # 从文件中读取数据
                    try:
                        df = pd.read_csv(_obj_fileinfo["save_path"])
                        xls_data = [MemberWeight.load_csv(data_row) for index, data_row in df.iterrows()]
                        _arry_update_data=[]
                        for i in xls_data:
                            try:
                                i["sex"] = "1" if i["sex"] == "女" else "0"
                                i["age"] = int(round(float(i["age"]), 0))
                                _arry_update_data.append(i)
                            except Exception as e1:
                                continue
                        # 读取到用户的上一个数据，写入到历史记录表
                        MemberWeightRoute.memberWeightServiceImpl.uploadMemWeightWithFile(rows=_arry_update_data)
                    except Exception as e:
                        return {'code': 99, 'data': None, 'message': MemberWeightRoute.ERROR_CODE["105"]}
                    return {'code': 200, 'data': None, 'message': ""}
